package com.cms.portal.security.filter;

import com.alibaba.fastjson.JSON;
import com.cms.context.constant.ConstantError;
import com.cms.context.constant.Constants;
import com.cms.context.utils.UtilsHttp;
import com.cms.context.utils.UtilsShiro;
import com.cms.core.foundation.Result;
import com.cms.service.api.CommonService;
import com.cms.service.api.ILogService;
import com.cms.service.dto.LogDto;
import com.cms.service.dto.UserDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.Objects;

/**
 * @author laolang
 * @version 1.0.0
 * @ClassName CmsAuthenticationFilter
 */
@Slf4j
public class CmsAuthenticationFilter extends FormAuthenticationFilter {
    @Autowired
    private CommonService commonService;
    @Autowired
    private ILogService logService;


    @Override
    protected boolean isLoginRequest(ServletRequest request, ServletResponse response) {
        return this.pathsMatch(this.getLoginUrl(),request) || this.pathsMatch(Constants.ADMIN_LOGIN,request);
    }

    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json; charset=UTF-8");
        PrintWriter writer = response.getWriter();
        String captcha = commonService.verifyImageCaptcha(WebUtils.getCleanParam(request, "captcha"));
        //TODO 跳过校验验证码
        if(1>2 && Objects.nonNull(captcha)){
           writer.write(JSON.toJSONString(Result.error(captcha)));
           writer.close();
            return false;
        }
        //获取前台传入的信息
        Subject subject = UtilsShiro.getSubject();
        //根据前台传回来的用户信息生成token
        AuthenticationToken token = this.createToken(request, response);
        try {
            subject.login(token);
            onLoginSuccess(token,subject,request,response);
            response.getWriter().write(JSON.toJSONString(Result.success(Constants.LOGIN_SUCCESS)));
        }catch (UnknownAccountException | IncorrectCredentialsException e){
            response.getWriter().write(JSON.toJSONString(Result.error(ConstantError.USERNAME_OR_PASSWORD_ERROR)));
        }

        writer.close();
        return false;
    }

    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest  httpServletRequest = (HttpServletRequest) request;
        String url = httpServletRequest.getRequestURI();

        String ip = UtilsHttp.getRemoteAddress();
        UserDto userDto = (UserDto) subject.getPrincipal();

        logService.save(LogDto.of(userDto.getId(),userDto.getUsername(),ip,url,"用户登录"));
        return false;
    }
}
